package nl.infodation.emr.pricingservice.ui.component;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.regex.Pattern;

import nl.infodation.emr.pricingservice.ui.page.SessionData;
import nl.infodation.emr.utility.Constants;

import com.vaadin.data.validator.IntegerValidator;
import com.vaadin.data.validator.StringLengthValidator;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.TextField;

public class PagingComponent extends CustomComponent implements Button.ClickListener, PropertyChangeListener {

	private static final long serialVersionUID = 1L;
	private final Button bFirst = new Button();
	private final Button bPrevious = new Button();
	private final Button bNext = new Button();
	private final Button bLast = new Button();
	private final HorizontalLayout pageNumbers = new HorizontalLayout();
	private static Pattern doublePattern = Pattern.compile("-?\\d+(\\.\\d*)?");
	private PagingModel model;
	private HorizontalLayout mainLayout;
	private TextField txtPage;
	private final Button btnGo = new NativeButton(SessionData.getI18N().getMessage(Constants.PAGING_BUTTON));
	
	public PagingComponent() {
		super();
		initLayout();
		setCompositionRoot(mainLayout);
		configureButtons();
	}

	private void initLayout() {
		setStyleName("paging");
		initButton(bFirst, "first");
		initButton(bPrevious, "previous");
		initButton(bNext, "next");
		initButton(bLast, "last");

		txtPage = new  TextField();
		txtPage.setImmediate(true);
		txtPage.addValidator(new IntegerValidator("Invalid integer {0}"));
		txtPage.setWidth(40,UNITS_PIXELS);
		txtPage.addValidator( new StringLengthValidator("Maximum length is " + Constants.TXT_PAGE_VALID_LEGHT, 0, Integer.parseInt(Constants.TXT_PAGE_VALID_LEGHT), true));
		
		btnGo.addListener(this);
//		btnGo.setWidth(100, Button.UNITS_PIXELS);
		btnGo.setStyleName("page_button");
		
		mainLayout = new HorizontalLayout();
		mainLayout.addComponent(bFirst);
		mainLayout.addComponent(bPrevious);
		mainLayout.addComponent(pageNumbers);
		mainLayout.addComponent(bNext);
		mainLayout.addComponent(bLast);
		mainLayout.addComponent(txtPage);
		mainLayout.addComponent(btnGo);

		
	}

	public PagingModel getModel() {
		return model;
	}

	public void setModel(final PagingModel model) {
		final PagingModel oldValue = model;
		this.model = model;

		if (oldValue != null) {
			oldValue.removePropertyChangeListener(this);
		}

		if (model != null) {
			model.addPropertyChangeListener(this);

		}

		configureButtons();
	}

	public final void configureButtons() {
		if (model == null) {
			bFirst.setEnabled(false);
			bPrevious.setEnabled(false);
			bNext.setEnabled(false);
			bLast.setEnabled(false);
		} else {
			/* Enable/Disable the navigation buttons */
			bFirst.setEnabled(!model.isFirstPage());
			bPrevious.setEnabled(model.hasPreviousPage());
			bNext.setEnabled(model.hasNextPage());
			bLast.setEnabled(!model.isLastPage());

			/* Refresh the page numbers displayed */
			pageNumbers.removeAllComponents();
			for (int pageNumber = model.getFirstPageNumbertoDisplay(); pageNumber <= model.getLastPageNumberToDisplay(); pageNumber++) {
				final Button pageButton = new Button(Integer.toString(pageNumber), new PageClickListener(pageNumber));
				pageButton.setStyleName("link");
				if (pageNumber == model.getCurrentPage()) {
					pageButton.addStyleName("current-page");
				}
				pageNumbers.addComponent(pageButton);
			}
		}
	}

	private void initButton(final Button button, final String iconPath) {
		button.addListener(this);
		button.setStyleName("link");
		button.addStyleName("navigation-button");
		button.setIcon(new ThemeResource("layouts/images/16/go-" + iconPath + ".png"));
		button.setEnabled(false);
	}

	public void propertyChange(final PropertyChangeEvent evt) {
		configureButtons();
	}

	public void buttonClick(final Button.ClickEvent event) {
		final Button clicked = event.getButton();
		if (clicked.equals(bFirst)) {
			model.setCurrentPage(1);
		} else if (clicked.equals(bPrevious)) {
			model.setCurrentPage(model.getCurrentPage() - 1);
		} else if (clicked.equals(bNext)) {
			model.setCurrentPage(model.getCurrentPage() + 1);
		} else if (clicked.equals(bLast)) {
			model.setCurrentPage(model.getTotalNumberOfPages());
		}else if(clicked.equals(btnGo)){
			double pageToGo = 0;
			if(isDouble(txtPage.getValue().toString())){
			pageToGo = Double.parseDouble((String) (txtPage.getValue()));
				if(pageToGo > 0 && pageToGo <= model.getTotalNumberOfPages()){
				model.setCurrentPage((int)pageToGo);
				}
			}
			
		}
	}
	
	private boolean isDouble(final String string) {
	    return doublePattern.matcher(string).matches();
	}

	private class PageClickListener implements Button.ClickListener, Serializable {
		private static final long serialVersionUID = 1L;
		
		private final int page;

		public PageClickListener(final int page) {this.page = page;}

		public void buttonClick(final Button.ClickEvent event) {
			model.setCurrentPage(page);
		}
	}
}
